package com.hunttown.mes.manage.controller._mes;

import com.hunttown.mes.common.OperateCode;
import com.hunttown.mes.manage.controller.common.AdminBaseClass;
import com.hunttown.mes.manage.controller.common.ModelService;
import com.hunttown.mes.manage.controller.vo.ShowInfoVo;
import com.hunttown.mes.rpc.domain.AnalysisManageDTO;
import com.hunttown.mes.rpc.domain.MesOrderMaterialDTO;
import com.hunttown.mes.rpc.domain.MesProductDTO;
import com.hunttown.mes.rpc.domain.TransportPurchaseDTO;
import com.hunttown.mes.rpc.domain.enums.mes.product.ProductStatusEnum;
import com.hunttown.mes.rpc.domain.enums.purchase.ProductTypeEnum;
import com.hunttown.mes.rpc.domain.query.MesOrderMaterialDTOQuery;
import com.hunttown.mes.rpc.domain.query.MesProductDTOQuery;
import com.hunttown.common.domain.Page;
import com.hunttown.mes.common.utils.JSONUtils;
import com.hunttown.mes.common.utils.StringUtils;
import com.hunttown.mes.manage.service.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.util.*;

import static com.hunttown.mes.common.utils.PageUtils.PagePackage;

/**
 * created by wangjunfu on 2022-03-30 15:32:55
 */
@Controller
@RequestMapping(value = "/mes/product")
public class MesProductController {

    private final static Logger logger = LoggerFactory.getLogger(MesProductController.class);

    private final MesProductManageService mesProductService;
    private final MesOrderMaterialManageService orderMaterialService;
    private final MesSaleOrderDetailManageService saleOrderDetailService;
    private final MesSaleExpressDetailManageService saleExpressDetailService;
    private final AnalysisManageManageService manageService;
    private final ModelService modelService;
    private final TransportPurchaseManageService purchaseService;

    @Autowired
    public MesProductController(MesProductManageService mesProductService, MesOrderMaterialManageService orderMaterialService, MesSaleOrderDetailManageService saleOrderDetailService, MesSaleExpressDetailManageService saleExpressDetailService, AnalysisManageManageService manageService, ModelService modelService, TransportPurchaseManageService purchaseService) {
        this.mesProductService = mesProductService;
        this.orderMaterialService = orderMaterialService;
        this.saleOrderDetailService = saleOrderDetailService;
        this.saleExpressDetailService = saleExpressDetailService;
        this.manageService = manageService;
        this.modelService = modelService;
        this.purchaseService = purchaseService;
    }

    //region 数据列表

    /**
     * 首页
     *
     * @param model    model模型
     * @param dtoQuery 查询条件
     * @return model
     */
    @RequestMapping(value = "/index", method = RequestMethod.GET)
    public String index(HttpServletRequest request, Model model, MesProductDTOQuery dtoQuery) {
        dtoQuery.setParentId(0);
        dtoQuery.setOrderBy("order by id desc");
        Page<MesProductDTO> dataPage = mesProductService.getForPage(dtoQuery);

        MesProductDTOQuery childQuery;
        Page<MesProductDTO> childPage;

        for (MesProductDTO item : dataPage.getItems()) {
            item.setPackageModeName(modelService.getCatalogName(item.getPackageMode()));
            item.setProductStatusName(ProductStatusEnum.getEnumByKey(item.getProductStatus()));

            //获取规格型号
            childQuery = new MesProductDTOQuery();
            childQuery.setParentId(item.getId());
            childQuery.setStopFlag(0);
            childQuery.setOrderBy("order by id desc");
            childPage = mesProductService.getForPage(childQuery);
            for (MesProductDTO ci : childPage.getItems()) {
                ci.setProductStatusName(ProductStatusEnum.getEnumByKey(ci.getProductStatus()));

                //计算库存
                //入库是生产的，出库是发货的，损坏暂时没有
                Long instore = saleOrderDetailService.getProductProduceCount(ci.getId());
                Long outstore = saleExpressDetailService.getProductSendCount(ci.getId());
                ci.setInStore(instore == null ? 0 : Integer.parseInt(instore + ""));
                ci.setOutStore(outstore == null ? 0 : Integer.parseInt(outstore + ""));
                ci.setDamageStore(0);
                ci.setStockStore(ci.getInStore() - ci.getOutStore());
            }
            item.setChildList(childPage.getItems());
        }

        model.addAttribute("page", dataPage);
        model.addAttribute("PagePackage", PagePackage(dataPage.getPn(), dataPage.getStart(), dataPage.getPageSize(), dataPage.getTotalPages(), dataPage.getTotalItems()));
        model.addAttribute("dtoQuery", dtoQuery);

        //region 页面按钮权限
        String pin = AdminBaseClass.getPin(request);
        String[] menus = {"C-C-CPXX-BJ", "C-C-CPXX-SC", "C-C-CPXX-QTY"};
        model.addAttribute("Permission", manageService.GetBtnPermission(menus, pin));
        //endregion

        return "mes/product/index";
    }
    //endregion

    //region 编辑&保存

    /**
     * 编辑
     *
     * @param model    model模型
     * @param id       主键id
     * @param parentId 添加型号时使用
     * @return model
     */
    @RequestMapping(value = "/edit", method = RequestMethod.GET)
    public String edit(Model model, Integer id, Integer parentId) {
        id = (id == null ? 0 : id);
        parentId = (parentId == null ? 0 : parentId);

        MesProductDTO obj = new MesProductDTO();

        if (id > 0) {
            obj = mesProductService.getById(id);
            obj.setPackageModeName(modelService.getCatalogName(obj.getPackageMode()));
            obj.setStorageName(modelService.getCatalogName(obj.getStorage()));
            obj.setProductStatusName(ProductStatusEnum.getEnumByKey(obj.getProductStatus()));

            //region 关联生产原料
            if (obj.getParentId() > 0) {
                MesOrderMaterialDTOQuery materiallQuery = new MesOrderMaterialDTOQuery();
                materiallQuery.setTableId(199);
                materiallQuery.setRecordId(id);
                materiallQuery.setPageSize(100);
                Page<MesOrderMaterialDTO> materialPage = orderMaterialService.getForPage(materiallQuery);
                for (MesOrderMaterialDTO item : materialPage.getItems()) {
                    item.setGoodsTypeName(ProductTypeEnum.getEnumByKey(item.getGoodsType()));
                }
                model.addAttribute("partsDetailList", materialPage.getItems());
            }
            //endregion

        } else {
            //添加规格型号
            if (parentId > 0) {
                MesProductDTO parentObj = mesProductService.getById(parentId);
                if (parentObj != null) {
                    obj = parentObj;
                    obj.setId(0);
                    obj.setParentId(parentId);
                    obj.setPackageModeName(modelService.getCatalogName(obj.getPackageMode()));
                    obj.setStorageName(modelService.getCatalogName(obj.getStorage()));
                    obj.setProductStatusName(ProductStatusEnum.getEnumByKey(obj.getProductStatus()));
                }
            } else {
                obj = new MesProductDTO();
                obj.setId(0);
                obj.setParentId(parentId);
                obj.setUnit("件");
                obj.setMarketPrice(BigDecimal.ZERO);
                obj.setSalePrice(BigDecimal.ZERO);
                obj.setProductStatus(1);
            }
        }

        model.addAttribute("Obj", obj);

        //封装形式
        modelService.getCatalogListForRecursion(model, 33, "packageModeList");

        //产品仓库
        modelService.getCatalogListForRecursion(model, 35, "storageList");

        //产品状态
        model.addAttribute("productStatusList", ProductStatusEnum.getEnumList());

        if (parentId == 0) {
            return "mes/product/edit";
        } else {
            return "mes/product/editSpecial";
        }
    }

    /**
     * 保存 ajax异步
     *
     * @param request sevelet请求
     * @param objDTO  实体类
     * @return json
     */
    @RequestMapping(value = "/saveEdit", method = RequestMethod.POST)
    @ResponseBody
    public String saveEditNotify(HttpServletRequest request, MesProductDTO objDTO) {

        // 结果返回 结果至少包含一个操作状态和一条状态信息
        String result = "";
        Map<String, String> map = new HashMap<String, String>();

        try {
            if (objDTO.getPackageMode() == null) {
                objDTO.setPackageMode(0);
            }
            if (objDTO.getMarketPrice() == null) {
                objDTO.setMarketPrice(BigDecimal.ZERO);
            }
            if (objDTO.getSalePrice() == null) {
                objDTO.setSalePrice(BigDecimal.ZERO);
            }
            if (objDTO.getStorage() == null) {
                objDTO.setStorage(0);
            }
            if (objDTO.getProductStatus() == null) {
                objDTO.setProductStatus(1);
            }
            if (objDTO.getMarketPrice() == null) {
                objDTO.setMarketPrice(BigDecimal.ZERO);
            }
            if (objDTO.getSalePrice() == null) {
                objDTO.setSalePrice(BigDecimal.ZERO);
            }

            //新增时检验是否唯一
            if ((objDTO.getId() == null || objDTO.getId() <= 0) && objDTO.getParentId() == 0) {
                MesProductDTOQuery query = new MesProductDTOQuery();
                query.setProductCode(objDTO.getProductCode());
                MesProductDTO obj = mesProductService.getByQuery(query);

                if (obj != null && obj.getId() > 0) {
                    //说明此记录已经存在，不能重复插入
                    map = OperateCode.CompositionResult(map, -10, "此产品已存在，请重新输入！");
                    result = JSONUtils.toJSON(map);
                    return result;
                }
            }

            if ((objDTO.getId() == null || objDTO.getId() <= 0) && objDTO.getParentId() > 0) {
                MesProductDTOQuery query = new MesProductDTOQuery();
                query.setSpecialName(objDTO.getSpecialName());
                MesProductDTO obj = mesProductService.getByQuery(query);

                if (obj != null && obj.getId() > 0) {
                    //说明此记录已经存在，不能重复插入
                    map = OperateCode.CompositionResult(map, -10, "此规格已存在，请重新输入！");
                    result = JSONUtils.toJSON(map);
                    return result;
                }
            }

            //型号规格时赋值一些信息，主产品更改时不会更新，所以要求强实时时，可动态去获取
            if (objDTO.getParentId() > 0) {
                MesProductDTO parent = mesProductService.getById(objDTO.getParentId());
                if (parent != null) {
                    objDTO.setProductName(parent.getProductName());
                    objDTO.setProductCode(parent.getProductCode());
                    objDTO.setChipName(parent.getChipName());
                    objDTO.setUnit(parent.getUnit());
                    objDTO.setPackageMode(parent.getPackageMode());
                    objDTO.setStorage(parent.getStorage());
                }
            }

            if (objDTO.getId() == null || objDTO.getId() <= 0) {
                //新增
                //设置初始值
                String pin = AdminBaseClass.getPin(request);
                AnalysisManageDTO curr_obj = manageService.getFromCachePin(pin);
                objDTO.setAdminId(curr_obj.getId());
                objDTO.setCreateTime(new Date());
                objDTO.setStopFlag(0);
                objDTO.setDeleteFlag(0);
                objDTO.setInStore(0);
                objDTO.setOutStore(0);
                objDTO.setDamageStore(0);
                objDTO.setStockStore(0);
                objDTO = mesProductService.insert(objDTO);

                if (objDTO == null || objDTO.getId() <= 0) {
                    //操作失败
                    map = OperateCode.CompositionResult(map, -1);
                    result = JSONUtils.toJSON(map);
                    return result;
                }

            } else {
                //更新
                //将不需要更新的字段设置为NULL
                Boolean isNext = mesProductService.updateInfoById(objDTO);

                if (!isNext) {
                    //操作失败
                    map = OperateCode.CompositionResult(map, -1);
                    result = JSONUtils.toJSON(map);
                    return result;
                }
            }

            //region [01].产品需要原料明细表.保存成功后更新
            if (objDTO.getParentId() > 0) {
                String[] f_id = request.getParameterValues("f_id");
                String[] f_partid = request.getParameterValues("f_partid");
                String[] f_count = request.getParameterValues("f_count");

                //1.获取已保存的原料明细
                MesOrderMaterialDTOQuery historyQuery = new MesOrderMaterialDTOQuery();
                historyQuery.setTableId(199);
                historyQuery.setRecordId(objDTO.getId());
                historyQuery.setPageSize(100);
                Page<MesOrderMaterialDTO> historyPage = orderMaterialService.getForPage(historyQuery);

                //2. 保存到数据库
                if (f_id != null && f_id.length > 0) {

                    List<Integer> newMaterailIds = new ArrayList<>(); //提交上来的，已保存过的ID
                    MesOrderMaterialDTO insert;
                    TransportPurchaseDTO partObj;

                    for (int i = 0; i < f_id.length; i++) {
                        int count = Integer.parseInt(f_count[i]);
                        if (count <= 0) {
                            continue;
                        }

                        int partid = Integer.parseInt(f_partid[i]);
                        if (partid <= 0) {
                            continue;
                        }

                        partObj = purchaseService.getById(partid);
                        if (partObj == null) {
                            continue;
                        }

                        insert = new MesOrderMaterialDTO();
                        insert.setTableId(199);
                        insert.setRecordId(objDTO.getId());
                        insert.setPartId(partid);
                        insert.setMaterialName(partObj.getPartName());
                        insert.setMaterialNo(partObj.getPartNo());
                        insert.setCatalogId(partObj.getCatalogId());
                        insert.setGoodsType(partObj.getProductType());
                        insert.setSpecialName(partObj.getSpecialName());
                        insert.setSn(partObj.getSnCode());
                        insert.setUnit(partObj.getUnit());
                        insert.setCount(count);
                        insert.setCountSingle(0);
                        insert.setCheckCount(0);
                        insert.setIsMaterialReady(0);
                        insert.setStorage(partObj.getStorage());
                        insert.setDeleteFlag(0);

                        //更新或插入
                        int id = Integer.parseInt(f_id[i]);
                        if (id > 0) {
                            //更新
                            newMaterailIds.add(id);
                            insert.setId(id);
                            orderMaterialService.updateInfoById(insert);
                        } else {
                            //插入
                            orderMaterialService.insert(insert);
                        }
                    }

                    //3.不存在新列表中的则表示已经删除了
                    for (MesOrderMaterialDTO item : historyPage.getItems()) {
                        if (!newMaterailIds.contains(item.getId())) {
                            orderMaterialService.delete(item.getId());
                        }
                    }
                }
            }
            //endregion

            //操作成功 结果返回
            map = OperateCode.CompositionResult(map, 1);
            result = JSONUtils.toJSON(map);
            return result;

        } catch (Exception e) {
            //清空map
            map.clear();
            map = OperateCode.CompositionResult(map, -1);
            result = JSONUtils.toJSON(map);
            return result;
        }
    }
    //endregion

    //region 删除&改变状态

    /**
     * 通过id删除 ajax异步
     *
     * @param id 记录id
     * @return json
     */
    @RequestMapping(value = "/deleteById", method = RequestMethod.POST)
    @ResponseBody
    public String deleteNotify(Integer id) {

        // 结果返回结果至少包含一个操作状态和一条状态信息
        String result = "";
        Map<String, String> map = new HashMap<String, String>();

        if (id == null || id <= 0) {
            map = OperateCode.CompositionResult(map, -10, "请选择要删除的记录！");
            result = JSONUtils.toJSON(map);
            return result;
        }

        try {
            Boolean isNext = mesProductService.delete(id);
            map = OperateCode.CompositionResult(map, isNext ? 1 : 0);
            result = JSONUtils.toJSON(map);
            return result;

        } catch (Exception e) {
            //清空map
            map.clear();
            map = OperateCode.CompositionResult(map, -1);
            result = JSONUtils.toJSON(map);
            return result;
        }
    }

    /**
     * 状态改变 ajax异步
     *
     * @param id     记录id
     * @param status 状态
     * @return json
     */
    @RequestMapping(value = "/changeFlag", method = RequestMethod.POST)
    @ResponseBody
    public String openOrStopFlag(Integer id, Integer status) {

        // 结果返回 结果至少包含一个操作状态和一条状态信息
        String result = "";
        Map<String, String> map = new HashMap<String, String>();

        try {
            Boolean isNext = mesProductService.changeState(id, status);
            map = OperateCode.CompositionResult(map, isNext ? 1 : 0);
            result = JSONUtils.toJSON(map);
            return result;

        } catch (Exception e) {
            //清空map
            map.clear();
            map = OperateCode.CompositionResult(map, -1);
            result = JSONUtils.toJSON(map);
            return result;
        }
    }
    //endregion

    //region 数据查看

    /**
     * 数据查看
     *
     * @param model     model模型
     * @param id        主键id
     * @param tableName 数据库英文表名
     * @return model
     */
    @RequestMapping(value = "/show", method = RequestMethod.POST)
    public String show(Model model, Integer id, String tableName) {
        id = (id == null ? 0 : id);

        MesProductDTO obj = new MesProductDTO();
        obj.setId(id);

        if (id > 0) {
            obj = mesProductService.getById(id);
        }
        model = mesProductService.assembleObjInfo(model, tableName, obj);

        return "show/show-template";
    }

    //详情
    @RequestMapping(value = "/getInfo", method = RequestMethod.POST)
    public String getInfo(Model model, Integer id) {

        //显示标题
        String showTitle = "未知";

        //数据
        ShowInfoVo vo;
        List<ShowInfoVo> dataList = new ArrayList<>();

        if (id != null && id > 0) {
            MesProductDTO obj = mesProductService.getById(id);

            if (obj != null) {
                showTitle = obj.getProductName();

                vo = new ShowInfoVo();
                vo.setKey("编号ID");
                vo.setValue(obj.getId());
                dataList.add(vo);

                vo = new ShowInfoVo();
                vo.setKey("产品名称");
                vo.setValue(obj.getProductName());
                dataList.add(vo);

                vo = new ShowInfoVo();
                vo.setKey("产品编码");
                vo.setValue(obj.getProductCode());
                dataList.add(vo);

                vo = new ShowInfoVo();
                vo.setKey("芯片名称");
                vo.setValue(obj.getChipName());
                dataList.add(vo);

                vo = new ShowInfoVo();
                vo.setKey("封装形式");
                vo.setValue(modelService.getCatalogName(obj.getPackageMode()));
                dataList.add(vo);

                vo = new ShowInfoVo();
                vo.setKey("单&emsp;&emsp;位");
                vo.setValue(obj.getUnit());
                dataList.add(vo);

                vo = new ShowInfoVo();
                vo.setKey("存储仓库");
                vo.setValue(modelService.getCatalogName(obj.getStorage()));
                dataList.add(vo);

                vo = new ShowInfoVo();
                vo.setKey("备注说明");
                vo.setValue(obj.getRemark());
                dataList.add(vo);

                //规格信息
                if (obj.getParentId() > 0) {
                    vo = new ShowInfoVo();
                    vo.setKey("规格型号");
                    vo.setValue(obj.getSpecialName());
                    dataList.add(vo);

                    vo = new ShowInfoVo();
                    vo.setKey("市&ensp;场&ensp;价");
                    vo.setValue(obj.getMarketPrice());
                    dataList.add(vo);

                    vo = new ShowInfoVo();
                    vo.setKey("销&ensp;售&ensp;价");
                    vo.setValue(obj.getSalePrice());
                    dataList.add(vo);

                    vo = new ShowInfoVo();
                    vo.setKey("生产状态");
                    vo.setValue(ProductStatusEnum.getEnumByKey(obj.getProductStatus()));
                    dataList.add(vo);

                    //产品原料
                    MesOrderMaterialDTOQuery materiallQuery = new MesOrderMaterialDTOQuery();
                    materiallQuery.setTableId(199);
                    materiallQuery.setRecordId(id);
                    materiallQuery.setPageSize(100);
                    Page<MesOrderMaterialDTO> materialPage = orderMaterialService.getForPage(materiallQuery);
                    for (MesOrderMaterialDTO item : materialPage.getItems()) {
                        item.setGoodsTypeName(ProductTypeEnum.getEnumByKey(item.getGoodsType()));
                    }
                    model.addAttribute("productMaterialList", materialPage.getItems());

                }
            }

            model.addAttribute("showTitle", showTitle);
            model.addAttribute("dataList", dataList);
        }

        return "show/getinfo-template";
    }

    //endregion

    //region 获取查询列表

    /**
     * 获取查询列表（带分页）
     *
     * @param name     关键词
     * @param from     0默认
     * @param pn       页码
     * @param pageSize 分页大小
     * @return map
     */
    @RequestMapping(value = "/selectProductPage", method = RequestMethod.POST)
    @ResponseBody
    public Map<Object, Object> selectProductPage(String name, Integer from, Integer pn, Integer pageSize) {
        pn = (pn == null || pn <= 0) ? 1 : pn;
        pageSize = (pageSize == null || pageSize <= 0) ? 5 : pageSize;

        Map<Object, Object> map = new HashMap<>();
        map.put("name", name);
        map.put("pn", pn);
        map.put("pageSize", pageSize);

        MesProductDTOQuery query = new MesProductDTOQuery();
        if (StringUtils.isNotBlank(name)) {
            query.setLikeName(name.trim());
        }
        query.setParentId(0);
        query.setPn(pn);
        query.setPageSize(pageSize);
        query.setStopFlag(0);
        query.setOrderBy("order by id desc");
        Page<MesProductDTO> dataPage = mesProductService.getForPage(query);

        //规格型号
        MesProductDTOQuery childQuery;
        Page<MesProductDTO> childPage;

        //新列表
        List<MesProductDTO> newProductList = new ArrayList<>();

        for (MesProductDTO item : dataPage.getItems()) {
            //获取规格型号
            childQuery = new MesProductDTOQuery();
            childQuery.setParentId(item.getId());
            childQuery.setStopFlag(0);
            childQuery.setOrderBy("order by id desc");
            childPage = mesProductService.getForPage(childQuery);

            for (MesProductDTO ci : childPage.getItems()) {
                ci.setProductName(item.getProductName());
                ci.setProductCode(item.getProductCode());
                ci.setChipName(item.getChipName());
                ci.setPackageModeName(modelService.getCatalogName(item.getPackageMode()));
                ci.setProductStatusName(ProductStatusEnum.getEnumByKey(ci.getProductStatus()));

                newProductList.add(ci);
            }
        }

        map.put("newProductList", newProductList);
        map.put("productAjaxPage", dataPage);
        map.put("productAjaxPagePackage", PagePackage(dataPage.getPn(), dataPage.getStart(), dataPage.getPageSize(), dataPage.getTotalPages(), dataPage.getTotalItems()));

        return map;
    }
    //endregion

    //region 获取单个产品的具体信息

    /**
     * 获取单个产品的具体信息
     *
     * @param productId 产品ID
     * @return map
     */
    @RequestMapping(value = "/getProductInfo", method = RequestMethod.POST)
    @ResponseBody
    public Map<Object, Object> getProductInfo(Integer productId) {
        Map<Object, Object> map = new HashMap<>();
        map.put("specialName", "");

        if (productId == null || productId <= 0) {
            return map;
        }

        MesProductDTO dto = mesProductService.getById(productId);
        if (dto != null) {
            map.put("specialName", dto.getSpecialName());
        }

        return map;
    }
    //endregion
}